<?php
/**
+-----------------------------------------------------------------------------------------------
* GouGuOPEN [ 左手研发，右手开源，未来可期！]
+-----------------------------------------------------------------------------------------------
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
+-----------------------------------------------------------------------------------------------
* @Licensed 勾股OA，开源且可免费使用，但并不是自由软件，未经授权许可不能去除勾股OA的相关版权信息
+-----------------------------------------------------------------------------------------------
* @Author勾股工作室 <hdm58@qq.com>
+-----------------------------------------------------------------------------------------------
*/
namespace app\lawcase\model;

use think\Model;
use think\facade\Db;

class CaseDoc extends Model
{
    // 设置当前模型对应的数据表名称
    protected $name = 'case_doc';
    
    // 设置数据表前缀
    protected $prefix = 'oa_';
    
    // 设置主键
    protected $pk = 'id';
    
    // 设置自动时间戳
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    
    // 设置JSON字段
    protected $json = ['file_ids'];

    /**
     * 获取案件文档列表
     * @param array $where 查询条件
     * @param array $param 分页参数
     * @return array|\think\Paginator
     */
    public function getList($where = [], $param = [])
    {
        $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
        $order = empty($param['order']) ? 'id desc' : $param['order'];
        try {
            $list = $this->where($where)
                ->where('delete_time', 0)
                ->order($order)
                ->paginate(['list_rows' => $rows, 'query' => $param])
                ->each(function($item) {
                    // 获取案件信息
                    $case = Db::name('lawcase')->where('id', $item->case_id)->find();
                    $item->case_code = $case ? $case['case_code'] : '';

                    // 获取上传用户信息
                    $uploader = Db::name('admin')->where('id', $item->upload_uid)->find();
                    $item->uploader_name = $uploader ? $uploader['name'] : '';

                    // 格式化文档类型
                    $item->doc_type_text = $this->getDocTypeText($item->doc_type);
                    
                    // 获取文件信息
                    $item->files = [];
                    if ($item->file_ids) {
                        // 处理file_ids字段，兼容JSON数组和逗号分隔字符串两种格式
                        if (is_string($item->file_ids) && strpos($item->file_ids, '[') === false) {
                            $fileIds = array_filter(explode(',', $item->file_ids));
                        } else {
                            $fileIds = is_object($item->file_ids) ? json_decode(json_encode($item->file_ids), true) : json_decode($item->file_ids, true);
                        }
                        if (is_array($fileIds) && !empty($fileIds)) {
                            $item->files = Db::name('file')->where('id', 'in', $fileIds)
                                ->field('id,name,filename,filepath,filesize,fileext')
                                ->select()
                                ->toArray();
                        }
                    }

                    // 格式化创建时间
                    $item->create_time_text = date('Y-m-d H:i:s', (int)$item->create_time);
                    $item->update_time_text = date('Y-m-d H:i:s', (int)$item->update_time);

                    return $item;
                });
            return $list;
        } catch (\Exception $e) {
            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
        }
    }

    /**
     * 添加案件文档
     * @param array $data 文档数据
     * @return int|string新增ID
     */
    public function add($data)
    {
        try {
            $data['create_time'] = time();
            $data['update_time'] = time();
            $insertId = $this->strict(false)->insertGetId($data);
            add_log('add', $insertId, $data);
        } catch (\Exception $e) {
            return to_assign(1, '操作失败，原因：'.$e->getMessage());
        }
        return to_assign(0,'操作成功',['return_id'=>$insertId]);
    }

    /**
     * 编辑案件文档
     * @param array $data 文档数据
     * @return bool
     */
    public function edit($data)
    {
        try {
            $data['update_time'] = time();
            $res = $this->strict(false)->where('id', $data['id'])->update($data);
            add_log('edit', $data['id'], $data);
            return $res !== false;
        } catch (\Exception $e) {
            throw new \Exception('编辑案件文档失败：' . $e->getMessage());
        }
    }

    /**
     * 删除案件文档
     * @param int|array $ids 文档ID或ID数组
     * @return bool
     */
    /**
     * 删除案件文档
     * @param int|array $ids 文档ID或ID数组
     * @return array
     */
    public function remove($ids)
    {
        Db::startTrans();
        try {
            $ids = is_array($ids) ? $ids : [$ids];
            
            // 获取所有文档的file_ids
            $docs = $this->where('id', 'in', $ids)->select();
            
            // 收集所有文件ID
            $fileIds = [];
            foreach ($docs as $doc) {
                if ($doc->file_ids) {
                    // 处理file_ids字段，兼容JSON数组和逗号分隔字符串两种格式
                    if (is_string($doc->file_ids) && strpos($doc->file_ids, '[') === false) {
                        $idsArray = array_filter(explode(',', $doc->file_ids));
                    } else {
                        $idsArray = is_object($doc->file_ids) ? json_decode(json_encode($doc->file_ids), true) : json_decode($doc->file_ids, true);
                    }
                    if (is_array($idsArray) && !empty($idsArray)) {
                        $fileIds = array_merge($fileIds, $idsArray);
                    }
                }
            }
            
            // 更新文件表
            if (!empty($fileIds)) {
                Db::name('file')->where('id', 'in', $fileIds)->update(['delete_time' => time()]);
            }
            
            // 更新文档表
            $this->where('id', 'in', $ids)->update(['delete_time' => time()]);
            
            // 添加日志
            foreach ($ids as $id) {
                add_log('delete', $id);
            }
            
            Db::commit();
            return to_assign();
        } catch (\Exception $e) {
            Db::rollback();
            return to_assign(11, '删除失败：' . $e->getMessage());
        }
    }

    /**
     * 获取案件文档详情
     * @param int $id 文档ID
     * @return array|null
     */
    public function getDetail($id)
    {
        $detail = $this->where(['id' => $id, 'delete_time' => 0])->find();
        if (!$detail) {
            return null;
        }

        $detail = $detail->toArray();

        // 获取案件信息
        $case = Db::name('lawcase')->where('id', $detail['case_id'])->find();
        $detail['case_name'] = $case ? $case['name'] : '';
        $detail['case_no'] = $case ? $case['case_no'] : '';

        // 获取上传用户信息
        $uploader = Db::name('admin')->where('id', $detail['upload_uid'])->find();
        $detail['uploader_name'] = $uploader ? $uploader['name'] : '';

        // 格式化文档类型
        $detail['doc_type_text'] = $this->getDocTypeText($detail['doc_type']);

        

        // 格式化创建时间
        $detail['create_time_text'] = date('Y-m-d H:i:s', $detail['create_time']);

        return $detail;
    }

    /**
     * 批量添加案件文档
     * @param int $caseId 案件ID
     * @param array $documents 文档数据 [['doc_type' => 1, 'title' => '文档标题', 'file_path' => '文件路径', ...], ...]
     * @return array添加结果，包含成功数量和失败数量
     */
    public function batchAdd($caseId, $documents)
    {
        $success = 0;
        $fail = 0;
        $time = time();Db::startTrans();
        try {
            foreach ($documents as $doc) {
                $data = [
                    'case_id' => $caseId,
                    'doc_type' => $doc['doc_type'],
                    'title' => $doc['title'],
                    'file_ids' => json_encode($doc['file_ids']),
                    'upload_uid' => $doc['upload_uid'],
                    'create_time' => $time
                ];
                $id = $this->strict(false)->insertGetId($data);
                if ($id) {
                    $success++;
                add_log('add', $id, $data);
                } else {
                    $fail++;
                }
            }
            Db::commit();
            return ['success' => $success, 'fail' => $fail];
        } catch (\Exception $e) {
            Db::rollback();
            throw new \Exception('批量添加案件文档失败：' . $e->getMessage());
        }
    }

    /**
     * 获取案件的所有文档
     * @param int $caseId 案件ID
     * @param int $docType 文档类型，0表示所有类型
     * @return array
     */
    public function getCaseDocuments($caseId, $docType = 0)
    {
        $query = $this->where(['case_id' => $caseId, 'delete_time' => 0]);

        if ($docType > 0) {
            $query->where('doc_type', $docType);
        }

        return $query->order('create_time desc')
            ->select()
            ->each(function($item) {
                $item['doc_type_text'] = $this->getDocTypeText($item['doc_type']);
                $item['file_size_text'] = format_bytes($item['file_size']);
                $item['create_time_text'] = date('Y-m-d H:i:s', $item['create_time']);
                return $item;
            })
            ->toArray();
    }

    /**
     * 更新文档信息
     * @param int $id 文档ID
     * @param array $data 更新数据
     * @return bool
     */
    public function updateDocument($id, $data)
    {
        try {
            $data['update_time'] = time();
            $res = $this->where('id', $id)->update($data);
            add_log('edit', $id, $data);
            return $res !== false;
        } catch (\Exception $e) {
            throw new \Exception('更新文档信息失败：' . $e->getMessage());
        }
    }

    /**
     * 获取文档类型文本
     * @param int $docType 文档类型值
     * @return string
     */
    protected function getDocTypeText($docType)
    {
        $types = [
            1 => '起诉状',
            2 => '委托代理材料',
            3 => '原被告身份证明',
            4 => '证据目录及证据材料',
            5 => '银行账户确认书',
            6 => '送达地址确认书',
            7 => '裁判文书/调解文书',
            8 => '其他'
        ];
        
        return isset($types[$docType]) ? $types[$docType] : '未知类型';
    }

    /**
     * 统计案件文档数量
     * @param int $caseId 案件ID
     * @return array包含各类型文档数量的数组
     */
    public function countCaseDocuments($caseId)
    {
        $counts = $this->where(['case_id' => $caseId, 'delete_time' => 0])
            ->group('doc_type')
            ->column('count(*)', 'doc_type');

        $result = [
            'total' => array_sum($counts),
            'contract' => $counts[1] ?? 0,
            'complaint' => $counts[2] ?? 0,
            'evidence' => $counts[3] ?? 0,
            'judgment' => $counts[4] ?? 0,
            'other' => $counts[5] ?? 0
        ];

        return $result;
    }

    /**
     * 搜索文档
     * @param string $keyword 关键词
     * @param int $caseId 案件ID，0表示搜索所有案件
     * @param int $limit 返回数量限制
     * @return array
     */
    public function searchDocuments($keyword, $caseId = 0, $limit = 10)
    {
        $query = $this->where('delete_time', 0)
            ->where(function($query) use ($keyword) {
                $query->where('title', 'like', "%{$keyword}%")
                    ->whereOr('file_path', 'like', "%{$keyword}%");
            });

        if ($caseId > 0) {
            $query->where('case_id', $caseId);
        }

        return $query->limit($limit)
            ->order('create_time desc')
            ->select()
            ->each(function($item) {
                $item['doc_type_text'] = $this->getDocTypeText($item['doc_type']);
                $item['file_size_text'] = format_bytes($item['file_size']);
                $item['create_time_text'] = date('Y-m-d H:i:s', $item['create_time']);
                return $item;
            })
            ->toArray();
    }

    /**
     * 获取最近上传的文档
     * @param int $limit 返回数量限制
     * @return array
     */
    public function getRecentDocuments($limit = 10)
    {
        return $this->where('delete_time', 0)
            ->order('create_time desc')
            ->limit($limit)
            ->select()
            ->each(function($item) {
                $item['doc_type_text'] = $this->getDocTypeText($item['doc_type']);
                $item['file_size_text'] = format_bytes($item['file_size']);
                $item['create_time_text'] = date('Y-m-d H:i:s', $item['create_time']);
                return $item;
            })
            ->toArray();
    }
}